#include "server.h"
#include "IOContextPool.h"
#include "../../log.h"

Server::Server(boost::asio::io_context& io_context, uint16_t port)
:m_acceptor(io_context, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
,m_port(port)
{
    _StartAccept();
}

void Server::DeleteSession(const std::string& uuid)
{
    std::unique_lock<std::mutex> lock(m_session_mtx);
    auto it = m_sessions.find(uuid);
    if (it != m_sessions.end())
    {
        m_sessions.erase(it);
    }
}

void Server::AddSession(const std::string& uuid, std::shared_ptr<Session> session)
{
    std::unique_lock<std::mutex> lock(m_session_mtx);
    m_sessions[uuid] = session;
}

void Server::_StartAccept()
{
    auto& io_context = IOContextPool::GetInstance().GetIOContext();
    auto session = std::make_shared<Session>(io_context, this);
    m_acceptor.async_accept(session->GetSocket(),[this, ptr = session](const boost::system::error_code& error){
        _HeadleAccetp(ptr, error);
    });
}

void Server::_HeadleAccetp(std::shared_ptr<Session> session, const boost::system::error_code& error)
{
    if(error)
    {
        log_error("HeadleAccetp error, error code: {}, error message: {}",error.value(), error.message());
        _StartAccept();
        return;
    }

    log_info("accept a new client, ip: {}", session->GetSocket().remote_endpoint().address().to_string());
    session->Start();
    AddSession(session->GetUUID(), session);

    _StartAccept();
}